#!/usr/bin/env python
# encoding: utf-8
"""
physics.py

Created by Morgan Quirk on 2007-08-11.
Copyright (c) 2007 Dragonfly Game Design. All rights reserved.
"""
import common
import math
import vector

class Physics:
    def __init__(self, levelarea, gridsize):
        self.grid = []
        self.gridsize=gridsize
        self.levelarea=levelarea
        self.setup_grid()
        self.update_rate = 4
        self.ticks=0
        self.push_damp = 4.0
        
    def setup_grid(self):
        x, y = self.levelarea
        for i in range(int(x / self.gridsize)+1):
            self.grid.append([])
            for j in range(int(y / self.gridsize)+1):
                self.grid[i].append([])
        
    def update_grid(self, ent_manager):
        self.setup_grid()
        for ent in ent_manager:
            img, (x1,y1,x2,y2) = ent.get_image()
            if x1<self.levelarea[0] and x2>0 and y1<self.levelarea[1] and y2>0:
                for i in range(int(x1/self.gridsize),int(x2/self.gridsize)+1):
                    for j in range(int(y1/self.gridsize), int(y2/self.gridsize)+1):
                        self.grid[i][j].append(ent)
        
    def tick(self, ent_manager):
        self.ticks+=1
            
        for ent1 in ent_manager:
            collision_list=[]
            img, (x1,y1,x2,y2) = ent1.get_image()
            if x1<self.levelarea[0] and x2>0 and y1<self.levelarea[1] and y2>0:                  
                for i in range(int(x1/self.gridsize),int(x2/self.gridsize)+1):
                    for j in range(int(y1/self.gridsize), int(y2/self.gridsize)+1):            
                        collision_list.extend(self.grid[i][j])
                for ent2 in list(set(collision_list)):
                    if ent2 is not ent1 and ent2 not in ent1.collided and ent1 not in ent2.collided:
                        self.collide(ent1, ent2)
                            
        for ent1 in ent_manager:
            ent1.collided = []
            for vect in ent1.forces:
                print vect.x, vect.y
                ent1.xv+=vect.x
                ent1.yv+=vect.y
            ent1.forces=[]
            ent1.x+=ent1.xv
            ent1.y+=ent1.yv
            ent1.xv *= ent1.global_friction
            ent1.yv *= ent1.global_friction
            ent1.xad = 0
            ent1.yad = 0
               
    def collide(self, ent1, ent2):
        if common.get_dist_sq(ent1.x - ent2.x, ent1.y - ent2.y) < (ent1.col_rad + ent2.col_rad) ** 2:
            ang  = common.get_angle(ent1.x - ent2.x, ent1.y - ent2.y) 
            dist = 0.5 + (((ent1.col_rad + ent2.col_rad) ** 2) -common.get_dist_sq(ent1.x - ent2.x, ent1.y - ent2.y)) / 20
            ent1.forces.append( vector.Vector(common.get_xy(ang, dist)))
            
            